package com.dhnsoft.map;

import com.dhnsoft.game.GameFrame;
import com.dhnsoft.game.LevelInfo;
import com.dhnsoft.tank.Tank;
import com.dhnsoft.util.Constant;
import com.dhnsoft.util.MapTilePool;
import com.dhnsoft.util.MyUtil;

import java.awt.*;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * @Description
 * @ClassName Map
 * @Author dhn
 * @date 2020.11.20 16:34
 */
/*
* 游戏地图类
* */
public class GameMap {
    private static final int MAP_X = Tank.RADIUS*3;
    private static final int MAP_Y = Tank.RADIUS*3+ GameFrame.titleBarH;
    private static final int MAP_WIDTH = Constant.FRAME_WIDTH-Tank.RADIUS*6;
    private static final int MAP_HEIGHT = Constant.FRAME_HEIGHT-Tank.RADIUS*8-GameFrame.titleBarH;

    private int width;
    private int height;

    //地图元素块的容器
    private List<MapTile> tiles = new ArrayList<>();
    private MapBuff buff = new MapBuff();

    public MapBuff getBuff() {
        return buff;
    }

    public void setBuff(MapBuff buff) {
        this.buff = buff;
    }

    //大本营
    private TankHouse house;

    public GameMap() {

    }

    /*
    * 初始化地图元素块 level 第几关
    * */
    public void initMap(int level){
        tiles.clear();
        try {
            loadLevel(level);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //初始化大本营
        house = new TankHouse();
        addHouse();
    }
    /*
    * 加载关卡信息
    * */
    private void loadLevel(int level) throws IOException {
        //获得关卡信息类的唯一实例对象
        LevelInfo levelInof = LevelInfo.getInstance();
        levelInof.setLevel(level);

        Properties prop = new Properties();
        prop.load(new FileInputStream("level/lv_"+level));
        //将所有的地图信息都加载进来
        int enemyCount = Integer.parseInt(prop.getProperty("enemyCount"));
        //设置敌人数量
        levelInof.setEnemyCount(enemyCount);

        //0,1 对敌人类型解析
        String[] enemyType = prop.getProperty("enemyType").split(",");
        int[] type = new int[enemyType.length];
        for (int i = 0; i < type.length; i++) {
            type[i] = Integer.parseInt(enemyType[i]);
        }
        //设置敌人类型
        levelInof.setEnemyType(type);
        //关卡难度 如果没有设置游戏难度，则当1处理
        String levelType = prop.getProperty("levelType");
        levelInof.setLevelType(Integer.parseInt(levelType==null?"1":levelType));

        String methodName = prop.getProperty("method");
        int invokeCount = Integer.parseInt(prop.getProperty("invokeCount"));
        //把实参都读取到数组中来。
        String[] params = new String[invokeCount];
        for (int i = 1; i <=invokeCount ; i++) {
            params[i-1] = prop.getProperty("param"+i);
        }
        //使用读取到的参数，调用对应的方法。
        invokeMethod(methodName,params);

    }
    //根据方法的名字和参数调用对应的方法
    private void invokeMethod(String name,String[] params){
        for (String param : params) {
            //获得每一行的方法的参数，解析。
            String[] split = param.split(",");
            //使用一个int 数组保存解析后的内容
            int[] arr = new int[split.length];
            int i;
            for (i = 0; i < split.length-1; i++) {
                arr[i] = Integer.parseInt(split[i]);
            }
            //块之间的间隔是地图块的倍数
            final int DIS = MapTile.tileW ;

            //解析最后一个double值
            int dis = (int)(Double.parseDouble(split[i])*DIS);
            switch(name){
                case "addRow":
                    addRow(MAP_X+arr[0]*DIS,MAP_Y+arr[1]*DIS,
                            MAP_X+MAP_WIDTH-arr[2]*DIS,arr[3],dis);
                    break;
                case "addCol":
                    addCol(MAP_X+arr[0]*DIS,MAP_Y+arr[1]*DIS,
                            MAP_Y+MAP_HEIGHT-arr[2]*DIS,
                            arr[3],dis);
                    break;
                case "addRect":
                    addRect(MAP_X+arr[0]*DIS,MAP_Y+arr[1]*DIS,
                            MAP_X+MAP_WIDTH-arr[2]*DIS,
                            MAP_Y+MAP_HEIGHT-arr[3]*DIS,
                            arr[4],dis);
                    break;
            }
        }
    }

    //将老巢的所有元素块添加到地图的容器中
    private void addHouse(){
        tiles.addAll(house.getTiles());

    }
    //某一个点确定的地图块是否和tiles集合中的所有块有重叠的部分
    private boolean isCollide(List<MapTile> tiles,int x,int y){
        for (MapTile tile : tiles) {
            int tileX = tile.getX();
            int tileY = tile.getY();
            if(Math.abs(tileX-x)<MapTile.tileW && Math.abs(tileY-y)<MapTile.tileW){
                return true;
            }
        }
        return false;
    }
    //只对没有遮挡效果的块进行绘制
    public void drawBK(Graphics g){
        for (MapTile tile : tiles) {
            if(tile.getType()!= MapTile.TYPE_COVER){
                tile.draw(g);
            }
        }
        house.draw(g);

    }
    //攻击buff效果的块进行绘制
    public void drawATK(Graphics g){
        buff.drawATK(g);

    }

    public void drawSpeed(Graphics g){
        buff.drawSpeed(g);

    }
    //对遮挡的块绘制
    public void drawCover(Graphics g){
        for (MapTile tile : tiles) {
            if(tile.getType()== MapTile.TYPE_COVER){
                tile.draw(g);
            }
        }
        house.draw(g);
    }

    public List<MapTile> getTiles() {
        return tiles;
    }
    /*
    * 将所有的不可见的地图块从容器中移出
    * */
    public void clearDestroyTile(){
        for (int i = 0; i < tiles.size(); i++) {
            MapTile mapTile = tiles.get(i);
            if(!mapTile.isVisible()){
                tiles.remove(i);
            }
        }
    }

    //往地图块容器中添加一行指定类型的地图块
    public void addRow(int startX,int startY,int endX,int type,final int DIS){
        int count=(endX - startX)/(MapTile.tileW+DIS);
            //如果是连续的，计算一行有多少个地图块

            for (int i = 0; i < count; i++) {
                MapTile tile = MapTilePool.get();
                tile.setType(type);
                tile.setX(startX + i*(MapTile.tileW+DIS));
                tile.setY(startY);
                tiles.add(tile);
            }
    }
    //往地图元素块容器中添加一列元素
    public void addCol(int startX,int startY,int endY,int type,final int DIS){
        int count  = (endY - startY +DIS)/(MapTile.tileW+DIS);
        for (int i = 0; i <count ; i++) {
            MapTile tile = MapTilePool.get();
            tile.setType(type);
            tile.setX(startX );
            tile.setY(startY + i * (MapTile.tileW+DIS));
            tiles.add(tile);
        }
    }
    //对指定的矩形区域添加元素块
    public void addRect(int startX,int startY,int endX,int endY,int type,final int DIS){
        int rows = (endY - startY)/(MapTile.tileW+DIS);
        for (int i = 0; i < rows; i++) {
            addRow(startX,startY+i*(MapTile.tileW+DIS),endX,type,DIS);
        }
        // int cols = (endX - startX)/(MapTile.tileW+DIS);
    }
}
